package com.util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

public class ImageUtil {

	static {
		System.setProperty("com.sun.media.jai.disableMediaLib", "true");
	}

	// 数字模板 0-9
	static int[][] value = {
			// num 0;
			{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
					0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
					0, 1, 1, 1, 0, 0 },
			// num 1
			{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
					0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
					0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
					0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
					1, 1, 1, 1, 1, 0 },
			// num2
			{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
					0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
					0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
					1, 1, 1, 1, 1, 0 },
			// num3
			{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
					1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
					1, 1, 1, 1, 0, 0 },
			// num4
			{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0,
					1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,
					1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,
					1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
					0, 0, 0, 0, 1, 0 },
			// num5
			{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
					0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
					0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
					1, 1, 1, 0, 0, 0 },
			// num6
			{ 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
					0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1,
					1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
					0, 1, 1, 1, 0, 0 },
			// num7
			{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
					0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
					0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
					1, 0, 0, 0, 0, 0 },
			// num8
			{ 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
					0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
					1, 1, 1, 1, 1, 0 },
			// num9
			{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
					0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
					1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
					0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
					1, 1, 1, 1, 0, 0 } };

	/**
	 * 识别图像
	 * 
	 * @param byteArray
	 * @return
	 * @throws Exception
	 */
	public static String recognize(byte[] byteArray) throws Exception {
		InputStream is = new ByteArrayInputStream(byteArray);
		BufferedImage image = ImageIO.read(is);
		return recognize(image);
	}

	/**
	 * 识别图像
	 * 
	 * @param image
	 * @return
	 * @throws Exception
	 */
	public static String recognize(BufferedImage image) throws Exception {
		StringBuffer sb = new StringBuffer("");
		BufferedImage newim[] = new BufferedImage[4];
		if (null == image) {
			throw new RuntimeException("iamage为null");
		}
		// 将图像分成四块，因为要处理的文件有四个数字。
		newim[0] = generateSingleColorBitMap(image.getSubimage(2, 1, 8, 11));
		newim[1] = generateSingleColorBitMap(image.getSubimage(11, 1, 8, 11));
		newim[2] = generateSingleColorBitMap(image.getSubimage(20, 1, 8, 11));
		newim[3] = generateSingleColorBitMap(image.getSubimage(29, 1, 8, 11));
		for (int k = 0; k < 4; k++) {
			int iw = newim[k].getWidth(null);
			int ih = newim[k].getHeight(null);
			int[] pix = new int[iw * ih];
			// 因为是二值图像，这里的方法将像素读取出来的同时，转换为0，1的图像数组。
			for (int i = 0; i < ih; i++) {
				for (int j = 0; j < iw; j++) {
					pix[i * (iw) + j] = newim[k].getRGB(j, i);
					if (pix[i * (iw) + j] == -1)
						pix[i * (iw) + j] = 0;
					else
						pix[i * (iw) + j] = 1;
				}
			}
			// 得到像匹配的数字。
			int r = getMatchNum(pix);
			sb.append(r);
		}
		return sb.toString();
	}

	/**
	 * 把单色位图转换成的0、1数组和字模数组进行比较，返回匹配的数字
	 * 
	 * @param pix
	 * @return
	 */
	private static int getMatchNum(int[] pix) {
		int result = -1;
		int temp = 100;
		int x;
		for (int k = 0; k <= 9; k++) {
			x = 0;
			for (int i = 0; i < pix.length; i++) {
				x = x + Math.abs(pix[i] - value[k][i]);
			}
			if (x == 0) {
				result = k;
				break;
			} else if (x < temp) {
				temp = x;
				result = k;
			}
		}
		return result;
	}

	/**
	 * 把彩色图像转换单色图像
	 * 
	 * @param colorImage
	 * @return
	 */
	private static BufferedImage generateSingleColorBitMap(Image colorImage) {
		BufferedImage image = new BufferedImage(8, 11,
				BufferedImage.TYPE_BYTE_GRAY);
		Graphics g = image.getGraphics();
		g.drawImage(colorImage, 0, 0, null);
		g.dispose();
		RenderedOp ro = JAI.create("binarize", image, new Double(100));
		BufferedImage bi = ro.getAsBufferedImage();
		return bi;
	}

	/**
	 * 测试
	 * 
	 * @param args
	 */
	public static void main(String args[]) throws Exception {
		String s = recognize(ImageIO.read(new File("D:/temp/image/jai/123.jpg")));
		System.out.println("" + s);
	}

}
